/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DBMS;

import admin.permisos.PermisosManager;
import clases.*;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.struts.upload.FormFile;

/**
 * Toma una matriz entera y modifica todas las columnas filas titulo nombre de
 * unidad y demas parametros persistentes presentes en la matriz
 *
 * @param m
 * @return
 */
//    public boolean modificarMatriz(Matriz m) {
//        throw new UnsupportedOperationException("Not yet implemented");
//    }
/**
 *
 * @author Luis Hernández Manejador de base de datos
 *
 */
public class DataBaseManager {

    /**
     *
     */
    public static List<Usuario> usuarios = new ArrayList<Usuario>();
    private static DataBaseManager instance = null;
    private static Connection conexion;
    private static boolean usuariosCalculados = false;
    private static ArrayList<String> fechas = new ArrayList<String>();

    private static void sincronizarUsuarios() {
        usuarios.clear();
        usuariosCalculados = false;
        usuarios = new ArrayList<Usuario>();
        getUsuarios();

    }
    private Usuario usuario = new Usuario();

    /**
     * Constructor clase DataBaseManager. Verifica la conexión con la base de
     * datos.
     */
    public DataBaseManager() {
    }

    /**
     * ***************************************************
     * GETTERS AND SETTERS *************************************************
     */
    /**
     * Obtiene una instancia del objeto DataBaseManager.
     *
     * @return instancia de DataBaseManager.
     */
    static public DataBaseManager getInstance() {
        if (null == DataBaseManager.instance) {
            DataBaseManager.instance = new DataBaseManager();
        }
        conectar();
        return DataBaseManager.instance;
    }

    /**
     * Obtiene usuarios de la base de datos
     */
    public static void getUsuarios() {
        try {
            if (usuariosCalculados == false || DataBaseManager.usuarios == null) {
                DataBaseManager.usuariosCalculados = true;
                Statement statement = DataBaseManager.conexion.createStatement();
                ResultSet query = statement.executeQuery("Select DISTINCT * from postgres.usuario ORDER BY usuario");
                System.out.println(query);
                int j = 0;
                while (query.next()) {
                    j++;
                    System.out.println("CARGANDO USUARIO" + j);
                    /*
                     * Aqui se agrego el atributo permiso
                     */
                    Usuario u = new Usuario(query.getString("usuario"), query.getString("password"), query.getString("nombre"), query.getString("correo"), query.getString("categoria"), query.getString("contacto"), query.getString("permiso"));
                    usuarios.add(u);
                }
                statement.close();
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    /**
     * **************************************************************
     *
     ****************************************************************
     * CONEXION - DESCONEXION A LA BASE DE DATOS
     * ***************************************************************
     */
    /**
     * Establece la conexión a la base de datos.
     *
     * @return booleano indicando si fue exitosa o no la conexión.
     */
    public static boolean conectar() {
        try {
            Class.forName("org.postgresql.Driver");
            conexion = DriverManager.getConnection(
                    "jdbc:postgresql://localhost:5432/postgres",
                    "postgres",
                    "postgres");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Se desconecta de la base de datos
     *
     */
    public void desconectar() {
        try {
            DataBaseManager.conexion.close();
            conexion = null;
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    public static ArrayList<String> getFechas() {
        return fechas;
    }

    /**
     * *******************************************************
     */
    /*
     * public Fecha getFecha() { Fecha fecha = null; try {
     * org.hibernate.Transaction tx = session.beginTransaction(); Query q =
     * session.createQuery("from Fecha"); fecha = (Fecha) q.list(); } catch
     * (Exception e) { } return fecha; }
     */
    /**
     * Verifica si el password y usuario que recibe se encuentran en la lista de
     * usuario.
     *
     * @param userLogin
     * @param userList
     * @return true si existe el usuario y password en la lista, false si no
     */
    public boolean loginAccess(Usuario userLogin, List userList) {
        if (userList != null) {
            Iterator i = userList.iterator();
            while (i.hasNext()) {
                Usuario u = (Usuario) i.next();
                if (u.getUsuario().equals(userLogin.getUsuario())) {
                    if (u.getPassword().equals(userLogin.getPassword())) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * **********************************************************
     * Operaciones de la Tabla Usuario
     * *********************************************************
     */
    /**
     * Verifica si el elemento existe en la base de datos
     *
     * @param usr
     * @return true si existe el elemento, false si no existe
     */
    public boolean existeUsuario(Usuario usr) {
        String value = usr.getUsuario();
        boolean existe = false;
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("select usuario from postgres.usuario where usuario ='" + value + "'");
            if (rs.next()) {
                if (rs.getString("usuario").equalsIgnoreCase(value)) {
                    System.out.println("Existe USUARIO");
                    return true;
                }
            }

            statement.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());

        }
        return false;
    }

    /**
     *
     * @param usr
     * @return
     */
    public Usuario consultarUsuario(Usuario usr) {
        List userList = DataBaseManager.usuarios;
        if (userList != null) {
            Iterator i = userList.iterator();
            while (i.hasNext()) {
                Usuario u = (Usuario) i.next();
                if (u.getUsuario().equalsIgnoreCase(usr.getUsuario())) {
                    return u;
                }
            }
        }
        return new Usuario();
    }

    /**
     * Este metodo debe regresar un usuario con todos son atributos seteados
     * para lograr esto se sugiere construir el query y luego tener una llamada
     * a un metodo generico que setee los atributos dado un result set.
     *
     * @param usr objeto con el usuario y la clave seteadas de manera tal que se
     * pueda consultar
     * @return Objeto usuario con los datos del usuario.
     */
    public Usuario validarRegistro(Usuario usr) {
        List userList = DataBaseManager.usuarios;
        if (userList != null) {
            Iterator i = userList.iterator();
            while (i.hasNext()) {
                Usuario u = (Usuario) i.next();
                if (usr.getUsuario() == null || u.getUsuario().equalsIgnoreCase(usr.getUsuario())) {
                    if (usr.getPassword() == null || u.getPassword().equalsIgnoreCase(usr.getPassword())) {
                        return u;
                    }
                }
            }
        }

        return new Usuario();
    }

    /**
     * Inserta un valor en una tabla de la base de datos
     *
     * @param usr
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean agregarUsuario(Usuario usr) {
        Connection c = DataBaseManager.conexion;
        int agregado = 0;

        try {
            Statement statement = c.createStatement();
            String query = "insert into postgres.usuario "
                    + "(usuario,password,nombre,correo,categoria, contacto, permiso) "
                    + "values('"
                    + usr.getUsuario() + "','" + usr.getPassword() + "','"
                    + usr.getNombre() + "','" + usr.getCorreo() + "','"
                    + usr.getCategoria() + "','" + usr.getContacto() + "','"
                    + (usr.getPermiso() == null ? "Admin Unidad" + usr.getCategoria() : usr.getPermiso()) + "')";
            System.out.println("Agregando Usuario" + query);
            agregado = statement.executeUpdate(query);
            DataBaseManager.sincronizarUsuarios();
            statement.close();
        } catch (SQLException sql) {
            System.err.println("Error: La inserción fue invalida");
            return false;
        }
        if (agregado > 0) {
            DataBaseManager.usuarios.add(usr);
        }
        return agregado > 0;

    }

    /**
     * Elimina un usuario de la base de datos
     *
     * @param usr
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean eliminarUsuario(Usuario usr) {
        boolean exitoso = true;
        try {
            Connection c = DataBaseManager.conexion;
            for (int i = 0; i < usuarios.size(); i++) {
                if (usuarios.get(i).getUsuario().equals(usr.getUsuario())) {
                    usuarios.remove(i);
                    break;
                }
            }
            if (usr.getUsuario() != null) {
                Statement statement = c.createStatement();
                String query = "delete from postgres.usuario where usuario ='" + usr.getUsuario() + "'";
                statement.executeUpdate(query);
                DataBaseManager.sincronizarUsuarios();
                statement.close();
                System.out.println(query);
            } else {
                return false;
            }
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return exitoso;
    }

    /**
     *
     * @param categoria
     * @return
     */
    public ArrayList<Usuario> consultarUsuarios(String categoria) {
        getUsuarios();
        ArrayList<Usuario> lista = new ArrayList<Usuario>();
        Iterator i = this.usuarios.iterator();
        while (i.hasNext()) {
            Usuario u = (Usuario) i.next();
            if (u.getCategoria() != null && u.getCategoria().equals(categoria)) {
                lista.add(u);
            }
        }
        return lista;
    }

    /**
     * Modifica información del usuario en la base de datos ej: nombre,
     * categoría, email.
     *
     * @param usr
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean modificarUsuario(Usuario usr) {
        Connection c = DataBaseManager.conexion;
        boolean exitoso = false;
        int modificado;
        String query = "";
        try {
            Statement s = c.createStatement();
            for (Usuario usuario : DataBaseManager.usuarios) {
                if (usuario.getUsuario().equals(usr.getUsuario())) {
                    usuario = usr;
                    exitoso = true;
                    System.out.println("Si existe el usuario");
                    System.out.println("Usuario Modificado" + usuario.getNombre());
                }
            }
            query = "Update postgres.usuario  set nombre = '"
                    + usr.getNombre() + "', correo='" + usr.getCorreo() + "', categoria='"
                    + usr.getCategoria() + "', contacto='" + usr.getContacto() + "' where usuario= '" + usr.getUsuario() + "'";
            modificado = s.executeUpdate(query);
            DataBaseManager.sincronizarUsuarios();
            System.out.println(query);
        } catch (SQLException e) {
            System.err.println(e.getMessage());
            System.out.println("Excepcion al modificar usuario");
            return false;
        }
        return modificado > 0;
    }

    /**
     * Retorna una lista con los usuarios de acuerdo a su categoría y los
     * imprime en pantalla.
     *
     * @param categoria
     * @param userList
     * @return objeto tipo Lista con los usuarios ordenados por categoria
     */
    public ArrayList<Usuario> categoriaUsuarios(String categoria, List userList) {
        ArrayList<Usuario> lista = new ArrayList<Usuario>();
        Iterator i = userList.iterator();
        while (i.hasNext()) {
            Usuario u = (Usuario) i.next();
            if (u.getCategoria() != null && u.getCategoria().equals(categoria)) {
                lista.add(u);
            }
        }
        return lista;
    }

    /**
     * Retorna el usuario pedido
     *
     * @param id
     * @return Objeto tipo usuario, con la información pedida.
     * @throws SQLException
     */
    public Usuario infoUser(String id) throws SQLException {
        List<Usuario> userList = DataBaseManager.usuarios;
        Iterator i = userList.iterator();
        while (i.hasNext()) {
            Usuario u = (Usuario) i.next();
            if (u.getUsuario().equals(id)) {
                return u;
            }
        }
        return null;
    }

    /**
     * *****************************************************************
     *
     *******************************************************************
     * Operaciones de la tabla Unidad
     * ****************************************************************** /**
     * Obtiene la lista de unidades
     *
     * @return lista de unidades.
     */
    public ArrayList<Unidad> getUnidades() {
        String query = " Select * from postgres.unidad ";
        try {
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            System.out.println(query);
            return toUnidades(rs);
        } catch (SQLException ex) {
            System.out.println("Problemas ejecutando el query: " + query);
        }
        return null;
    }

    private ArrayList<Unidad> toUnidades(ResultSet rs) {
        try {
            ArrayList<Unidad> unidades = new ArrayList<Unidad>();
            Unidad u = null;
            while (rs.next()) {
                u = new Unidad();
                u.setCodigo(rs.getString("codigo"));
                u.setDescripcion(rs.getString("descripcion"));
                System.out.println("Cargando unidades...");
                Usuario usr = new Usuario();
                u.setRepresentantes(this.consultarUsuarios(u.getCodigo()));
                unidades.add(u);
            }
            return unidades;
        } catch (SQLException ex) {
            System.out.println("Problema cargando unidades en el login");
        }
        return null;
    }

    /**
     *
     * @param unidad
     * @return
     */
    private ArrayList<Usuario> buscarRepresentantes(Unidad unidad) {
        ArrayList<Usuario> representantes = new ArrayList<Usuario>();

        for (int i = 0; i < usuarios.size(); i++) {
            if (usuarios.get(i).getCategoria().equals(unidad.getDescripcion())
                    || usuarios.get(i).getCategoria().equals(unidad.getCodigo())) {
                representantes.add(usuarios.get(i));
            }
        }
        System.out.println("Usuarios para la unidad " + unidad.getCodigo());
        for (Usuario usr : representantes) {
            System.out.println(usr.getNombre());
        }

        //unidad.setRepresentantes(representantes);
        return representantes;
    }

    /**
     * Verifica si el elemento existe en la base de datos
     *
     * @param value
     * @return true si existe el elemento, false si no existe
     */
    public boolean existeUnidad(String value) {
        boolean existe = false;
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("select codigo from postgres.unidad where codigo='" + value + "'");
            if (rs.next()) {
                if (rs.getString("codigo").equalsIgnoreCase(value)) {
                    existe = true;
                }
            }

            statement.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return false;

        }
        return existe;
    }

    /**
     * Este metodo funciona para agregar una unidad con un codigoCategoria
     * establecido y un nombre establecido
     *
     * @param u
     * @return true si logro agregar la unidad false en otros casos
     */
    public boolean agregarUnidad(Unidad u) {
        Connection c = DataBaseManager.conexion;

        try {
            Statement statement = c.createStatement();
            String query = "insert into unidad (codigo,descripcion) values('" + u.getCodigo() + "','" + u.getDescripcion() + "')";
            statement.executeUpdate(query);
            System.out.print(query);
            statement.close();
        } catch (SQLException sql) {
            System.err.println("Error: La inserción fue invalida");
            return false;
        }

        return true;


    }

    /**
     *
     * @param unidad
     * @return
     */
    public Unidad consultarUnidad(Unidad unidad) {
        try {
            String query = " SELECT * from postgres.unidad  WHERE codigo = \'" + unidad.getCodigo() + "\'";
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" PROBLEMA Consultando unidad por codigo no obtuvo resultados");
                return null;
            }
            unidad.setCodigo(rs.getString("codigo"));
            unidad.setDescripcion(rs.getString("descripcion"));
            System.out.println(query);
            unidad.setRepresentantes(buscarRepresentantes(unidad));
            unidad.setCategorias(consultarCategorias(unidad));
            return unidad;

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return unidad;
    }

    /**
     * @param uniForm
     * @return Un array list con todas las unidades que cumplan con las
     * condiciones del objeto si el objeto tiene campos nulos o vacios se
     * consulta a todas las que tienen ese objeto. Recuerda setear siempre los
     * atributos como representantes con su respectivo JOIN
     */
    public ArrayList<Unidad> consultarUnidades(Unidad uniForm) {
        ArrayList<Unidad> listUnidad = new ArrayList<Unidad>();
        try {
            List<Usuario> userList = DataBaseManager.usuarios;
            if (!conexion.isClosed()) {
                Statement statement = DataBaseManager.conexion.createStatement();
                String query = "Select * from postgres.unidad";
                ResultSet resultSet = statement.executeQuery(query);
                while (resultSet.next()) {
                    if (uniForm.getCodigo() == null || resultSet.getString("codigo").startsWith(uniForm.getCodigo())) {
                        if (uniForm.getDescripcion() == null || resultSet.getString("descripcion").startsWith(uniForm.getDescripcion())) {
                            ArrayList<Usuario> usuarioUnidad = new ArrayList<Usuario>();
                            usuarioUnidad = categoriaUsuarios(resultSet.getString("codigo"), userList);
                            Unidad u = new Unidad(resultSet.getString("codigo"), resultSet.getString("descripcion"), usuarioUnidad);
                            listUnidad.add(u);
                        }
                    }
                }
                System.out.println("Usuarios totales del sistema");
                for (Object usr : usuarios) {
                    System.out.println(((Usuario) usr).getNombre());
                }
                statement.close();
            }

        } catch (Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            return null;

        }
        return listUnidad;

    }

    public ArrayList<Categoria> consultarCategorias(Unidad uniForm) {

        String query = "SELECT * from postgres.categoria where codigounidad='" + uniForm.getCodigo() + "'";
        System.out.println(query);
        ArrayList<Categoria> listaCategorias = new ArrayList<Categoria>(0);
        try {
            if (!conexion.isClosed()) {
                Statement stat = conexion.createStatement();
                ResultSet rs = stat.executeQuery(query);
                while (rs.next()) {
                    Categoria cat = new Categoria();
                    System.out.println("Cod. Categoria:" + rs.getString("codigo"));
                    System.out.println("Nombre Categoria:" + rs.getString("nombre"));
                    System.out.println(("Codigo Unidad:") + rs.getString("codigounidad"));
                    cat.setCodigoCategoria(rs.getString("codigo"));
                    cat.setNombre(rs.getString("nombre"));
                    cat.setCodigoUnidad(rs.getString("codigounidad"));
                    listaCategorias.add(cat);
                }
            }
        } catch (SQLException sql) {
            sql.printStackTrace();
        }
        return listaCategorias;
    }

    /**
     * Eliminar una unidad Intenta eliminar el objeto pasado como parametro si
     * lo logra devuelve true en otros casos false. Verificar los ondelete
     * cascade
     *
     * @param uni
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean eliminarUnidad(Unidad uni) {
        boolean exitoso = true;
        try {
            Connection c = DataBaseManager.conexion;
            Statement statement = c.createStatement();
            statement.executeUpdate("delete from postgres.unidad where codigo='" + uni.codigo + "'");
            statement.close();
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return exitoso;

    }

    /**
     * Modifica en la tabla de bases de dato una unidad, además, modifica la
     * unidad de todos los representantes que tengan como unidad aquella
     * modificada.
     *
     * @param uni
     * @return booleano indicando si fue exitosa la operación.
     */
    public boolean modificarUnidad(Unidad uni) {
        Connection c = DataBaseManager.conexion;
        String query = "";
        try {
            Statement statement = c.createStatement();
            query = "Update unidad\n set descripcion='" + uni.getDescripcion() + "' where codigo= '" + uni.getCodigo() + "'";
            statement.executeUpdate(query);
        } catch (SQLException sql) {
            System.err.println("error en la actualización del usuario");
            return false;
        }

        return true;
    }

    /**
     * *************************************************
     * OPERACIONES DE CALENDARIO *
     * *************************************************
     */
    /**
     * Agrega una nueva entrada en la tabla de Calendarios.
     *
     * @param calendario Instancia del calendario que sera agregada a la tabla.
     * @return true si se agrego exitosamente. False en caso contrario.
     */
    public boolean agregarCalendario(Calendario calendario) {
        Connection c = DataBaseManager.conexion;

        try {
            Statement instruccion = c.createStatement();
            instruccion.executeUpdate("insert into postgres.calendario "
                    + "(fecha_inicio, fecha_fin) " + "values('"
                    + calendario.getFechaInicio() + "','"
                    + calendario.getFechaFin() + "')");
            instruccion.close();
        } catch (SQLException sql) {
            System.err.println("Error: La inserción fue invalida");
            return false;
        }

        return true;
    }

    /**
     * Elimina una entrada de la tabla de Calendarios.
     *
     * @param calendario Instancia del calendario que va a ser eliminada.
     * @return true si se elimino exitosamente. False en caso contrario.
     */
    public boolean eliminarCalendario(Calendario calendario) {

        try {
            Connection c = DataBaseManager.conexion;
            Statement instruccion = c.createStatement();
            instruccion.executeUpdate("delete from postgres.calendario where "
                    + "fecha_inicio='" + calendario.getFechaInicio()
                    + "' and fecha_fin='" + calendario.getFechaFin() + "';");
            instruccion.close();
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return true;
    }

    /**
     * Modifica una entrada de la tabla de Calendarios.
     *
     * @param calendario Instancia del calendario a ser modificada.
     * @return true si se modifico exitosamente. False en caso contrario.
     */
    public boolean modificarCalendario(Calendario calendario) {
        return true;
    }

    /**
     * *************************************************
     * OPERACIONES DE RECORDATORIO
     * ************************************************
     */
    /**
     * @param recordatorio
     * @return agrega un recordatorio a la base de datos.
     */
    public boolean agregarRecordatorio(Recordatorio recordatorio) {
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            System.out.println("Voy a agregar el recordatorio");
            System.out.println("insert into postgres.recordatorio (fechainicio,fechafinal,nombre,unidad,matriz,tipo,ano) values('" + recordatorio.getFechaInicio() + "','" + recordatorio.getFechaFin() + "','" + recordatorio.getNombre() + "','" + recordatorio.getUnidad() + "','" + recordatorio.getMatriz() + "','" + recordatorio.getTipo() + "','" + recordatorio.getAno() + "')");
            statement.executeUpdate("insert into postgres.recordatorio (fechainicio,fechafinal,nombre,unidad,matriz,tipo ,ano) values('" + recordatorio.getFechaInicio() + "','" + recordatorio.getFechaFin() + "','" + recordatorio.getNombre() + "','" + recordatorio.getUnidad() + "','" + recordatorio.getMatriz() + "','" + recordatorio.getTipo() + "','" + recordatorio.getAno() + "')");
            System.out.println("Se agrego el recordatorio");

            statement.close();

        } catch (SQLException sql) {
            System.err.println("Error: La inserción fue invalida");
            return false;
        }

        return true;

    }

    /**
     * Hace la eliminacion de un recordatorio
     *
     * @param rec
     * @return indicador de si fue exitosa la eliminacion.
     */
    public boolean eliminarRecordatorio(Recordatorio rec) {
        boolean exitoso = true;
        System.out.println("delete from postgres.recordatorio where fechainicio='"
                + rec.getFechaInicio() + "' AND fechafinal='"
                + rec.getFechaFin() + "'");
        try {
            Connection c = DataBaseManager.conexion;
            Statement statement = c.createStatement();
            statement.executeUpdate("delete from postgres.recordatorio where fechainicio='"
                    + rec.getFechaInicio() + "' AND fechafinal='"
                    + rec.getFechaFin() + "'");

            statement.close();
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return exitoso;

    }

    /**
     * Modifica un recordatorio
     *
     * @param rec
     * @return indicador de si fue válida la actualización.
     */
    public boolean modificarRecordatorio(Recordatorio rec) {
        Connection c = DataBaseManager.conexion;
        String query = "";
        try {
            Statement statement = c.createStatement();
            query = "update recordatorio\n set fechainicio='" + rec.getFechaInicio() + "',fechafinal='" + rec.getFechaFin() + "' where nombre= '" + rec.getNombre() + "'";
            statement.executeUpdate(query);
        } catch (SQLException sql) {
            System.err.println("error en la actualización del usuario");
            return false;
        }

        return true;
    }

    /**
     * Hace la consulta de los recordatorios que se encuentran en la base de
     * datos.
     *
     * @param rec
     * @return lista de recordatorios.
     */
    public ArrayList<Recordatorio> consultarRecordatorios(Recordatorio rec) {
        ArrayList<Recordatorio> recordatorios = new ArrayList<Recordatorio>(0);
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("Select * from recordatorio ORDER BY fechafinal");
            while (rs.next()) {
                Recordatorio r = new Recordatorio(rs.getString("id"), rs.getString("fechainicio"), rs.getString("fechafinal"), rs.getString("unidad"), rs.getString("matriz"), rs.getString("tipo"));
                r.setNombre(rs.getString("nombre"));
                r.setAno(rs.getString("ano"));
                System.out.println("consultando recordatorio " + rs.getString("nombre"));
                recordatorios.add(r);
            }

        } catch (SQLException sql) {
            System.err.println("Error en la consulta de recordatorio");
            return null;
        }


        return recordatorios;
    }

    /**
     * Recordatorio mas reciente de una matriz dada
     *
     * @param idMatriz : Id de la matriz a considerar
     * @return r Recordatorio mas reciente de la matriz con idMatriz
     */
    public Recordatorio consultarRecordatorioPorMatriz(Matriz matriz) {
        Connection c = DataBaseManager.conexion;
        Recordatorio r = null;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("Select * from recordatorio WHERE matriz =" + matriz.getIdMatriz() + " ORDER BY fechafinal");
            if (rs.next()) {
                r = new Recordatorio(rs.getString("id"), rs.getString("fechainicio"), rs.getString("fechafinal"), rs.getString("unidad"), rs.getString("matriz"), rs.getString("tipo"));
                r.setAno(rs.getString("ano"));
            }
        } catch (SQLException sql) {
            System.err.println("Error en la consulta de recordatorio");
            return null;
        }
        return r;
    }

    /**
     * Hace la consulta de los recordatorios que se encuentran en la base de
     * datos.
     *
     * @param rec
     * @return lista de recordatorios.
     */
    public Recordatorio consultarRecordatorio(Recordatorio rec) {
        ArrayList<Recordatorio> recordatorios = new ArrayList<Recordatorio>(0);
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("Select * from recordatorio");
            while (rs.next()) {
                Recordatorio r = new Recordatorio(rs.getString("id"), rs.getString("fechainicio"), rs.getString("fechafinal"), rs.getString("unidad"), rs.getString("matriz"));
                r.setAno(rs.getString("ano"));
                recordatorios.add(r);

            }

        } catch (SQLException sql) {
            System.err.println("Error en la consulta de recordatorio");
            return null;
        }


        return rec;
    }

    /**
     * *******************************************************************
     * OPERACIONES DE MATRIZ
     *
     ********************************************************************
     */
    /**
     *
     * @param matriz
     * @return
     */
    /*
     * public boolean agregarMatrizFile(MatrizFile matriz) { int matrizAgregada
     * = 0; System.out.println("hola"); try { String sqlquery = "insert into
     * postgres.matrizFile (pathabsoluto , fechacreacion, codigoCategoria ,
     * nombre) values('" + matriz.getPathAbsoluto() + "','" +
     * matriz.getFechaCreacion() + "','" + matriz.getUnidad() + "','" +
     * matriz.getNombre() + "')"; System.out.println(matriz.getUnidad());
     * Statement stmt = DataBaseManager.conexion.createStatement();
     * System.out.println(sqlquery); matrizAgregada =
     * stmt.executeUpdate(sqlquery);
     *
     * } catch (SQLException ex) { ex.printStackTrace(); return false; }
     *
     * return matrizAgregada > 0; }
     */
    /**
     *
     * @param matriz
     * @return
     */
    /*
     * public boolean eliminarMatrizFile(MatrizFile matriz) { int
     * matrizEliminada = 0; try { Statement stmt = conexion.createStatement();
     * String sqlquery = "delete * from postgres.matrizFile where " +
     * "pathabsoluto='" + matriz.getPathAbsoluto() + "' AND " +
     * "fechacreacion='" + matriz.getFechaCreacion() + "' AND" + "nombre='" +
     * matriz.getNombre(); stmt.executeUpdate(sqlquery);
     * System.out.println(sqlquery);
     *
     * } catch (SQLException ex) { ex.printStackTrace(); return false;
     *
     * }
     * return matrizEliminada > 0; }
     */
    /**
     *
     * @return
     */
    /*
     * public ArrayList<MatrizFile> consultarMatrices() { ArrayList<MatrizFile>
     * matrices = new ArrayList<MatrizFile>(); try { String sqlquery = "Select *
     * from postgres.matrizFile; "; Statement stmt =
     * DataBaseManager.conexion.createStatement(); ResultSet rs =
     * stmt.executeQuery(sqlquery); while (rs.next()) {
     * matrices.add(toMatriz(rs)); } return matrices; } catch (SQLException ex)
     * { ex.printStackTrace(); } return matrices; }
     */
    /*
     * private MatrizFile toMatriz(ResultSet rs) { MatrizFile matriz = new
     * MatrizFile(); try {
     * matriz.setFechaCreacion(rs.getString("fechacreacion"));
     * matriz.setPathAbsoluto(rs.getString("pathabsoluto"));
     * matriz.setNombre(rs.getString("nombre"));
     * matriz.setUnidad(rs.getString("codigoCategoria"));
     * System.out.println("Matriz dentro del sistema");
     * System.out.println(matriz.getNombre()+matriz.getFechaCreacion()+matriz.getUnidad());
     * return matriz; } catch (SQLException ex) { ex.printStackTrace(); } return
     * matriz; }
     */
    /**
     *
     * @param uni
     * @return
     */
    /*
     * public ArrayList<MatrizFile> consultarMatrices(Unidad uni) {
     * ArrayList<MatrizFile> matrices = new ArrayList<MatrizFile>(); try {
     * String sqlquery = "Select * from postgres.matrizFile where
     * codigoCategoria = " +"'" + uni.getCodigoCategoria()+"'"; Statement stmt =
     * DataBaseManager.conexion.createStatement(); ResultSet rs =
     * stmt.executeQuery(sqlquery); while (rs.next()) {
     * matrices.add(toMatriz(rs)); } return matrices; } catch (SQLException ex)
     * { ex.printStackTrace(); } return matrices; }
     */
    /**
     * *******************************************************************
     * OPERACIONES DE CATEGORIA
     *
     ********************************************************************
     */
    /**
     * Obtiene la lista completa de categorias.
     *
     * @return Lista de Categorias.
     */
    public ArrayList<Categoria> getCategorias() {
        String query = " Select * from postgres.categoria ";
        try {
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            return toCategorias(rs);
        } catch (SQLException ex) {
            System.out.println("Problemas ejecutando el query: " + query);
        }
        return null;
    }

    private ArrayList<Categoria> toCategorias(ResultSet rs) {
        try {
            ArrayList<Categoria> Categorias = new ArrayList<Categoria>();
            Categoria cat = null;
            while (rs.next()) {
                cat = new Categoria();
                cat.setCodigoCategoria(rs.getString("codigo"));
                cat.setCodigoUnidad(rs.getString("codigounidad"));
                cat.setNombre(rs.getString("nombre"));
                System.out.println("Cargando categorias...");
                Categorias.add(cat);
            }
            return Categorias;
        } catch (SQLException ex) {
            System.out.println("Problema cargando las categorias");
        }
        return null;
    }

    /**
     * ****Hace falta acomodar esta funcion! Busca en una unidad todas las
     * categorias que pertenecen a esta
     *
     * @param unidad Objeto de tipo Unidad, con la unidad a la que se le desean
     * buscar categorias.
     * @return Objeto Unidad con las categorias agregadas.
     */
    private Unidad buscarCategorias(Unidad unidad) {
        Connection conexion = DataBaseManager.conexion;
        String query = "SELECT * from postgres.categoria where codigounidad = '" + unidad.getCodigo() + "'";
        try {
            Statement statement = conexion.createStatement();
            ResultSet rs = statement.executeQuery(query);
            ArrayList categorias = toCategorias(rs);
            unidad.setCategorias(categorias);
        } catch (SQLException sql) {
            sql.printStackTrace();
        }


        return unidad;
    }

    /**
     * Verifica si el elemento existe en la base de datos
     *
     * @param value
     * @return true si existe el elemento, false si no existe
     */
    public boolean existeCategoria(String value) {
        boolean existe = false;
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("select codigo from postgres.categoria where codigo='" + value + "'");
            if (rs.next()) {
                if (rs.getString("codigo").equalsIgnoreCase(value)) {
                    existe = true;
                }
            }

            statement.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return false;

        }
        return existe;
    }

    /**
     * Este metodo funciona para agregar una categoria con un codigoCategoria
     * establecido y un nombre establecido
     *
     * @param a
     * @return true si logro agregar la unidad false en otros casos
     */
    public boolean agregarCategoria(Categoria categoriaAgregar) {
        Connection c = DataBaseManager.conexion;

        try {
            Statement statement = c.createStatement();
            statement.executeUpdate("insert into postgres.categoria (codigo,codigounidad,nombre) values('" + categoriaAgregar.getCodigoCategoria() + "','" + categoriaAgregar.getCodigoUnidad() + "','" + categoriaAgregar.getNombre() + "')");
            statement.close();
        } catch (SQLException sql) {
            System.err.println("Error: La inserción fue invalida");
            return false;
        }

        return true;


    }

    /**
     * Eliminar categoria Intenta eliminar el objeto pasado como parametro si lo
     * logra devuelve true en otros casos false. Verificar los ondelete cascade
     *
     * @param categoriaElim Objeto Categoria con la informacion de la Categoria
     * a eliminar.
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean eliminarCategoria(Categoria categoriaElim) {
        boolean exitoso = true;
        try {
            Connection c = DataBaseManager.conexion;
            Statement statement = c.createStatement();
            if (categoriaElim.getCodigoCategoria() == null) {
                return false;
            }
            statement.executeUpdate("delete from postgres.categoria where codigo='" + categoriaElim.codigoCategoria + "'");
            statement.close();
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return exitoso;

    }

    /**
     * Modifica en la tabla de bases de dato una categoria.
     *
     * @param categoriaMod Categoria a modificar
     * @return booleano indicando si fue exitosa la operación.
     */
    public boolean modificarCategoria(Categoria categoriaMod) {
        Connection c = DataBaseManager.conexion;
        String query = "";
        try {
            Statement statement = c.createStatement();
            query = "Update postgres.categoria\n set nombre='" + categoriaMod.getNombre() + "' where codigo= '" + categoriaMod.getCodigoCategoria() + "'";
            statement.executeUpdate(query);
        } catch (SQLException sql) {
            System.err.println("error en la actualización de la Categoria");
            return false;
        }

        return true;
    }

    /**
     * Consulta una categoria en especifico.
     *
     * @param cat
     * @return objeto Categoria con la categoria solicitada.
     */
    public Categoria consultarCategoria(Categoria cat) {
        try {
            String query = " SELECT * from postgres.categoria  WHERE codigo = \'" + cat.getCodigoCategoria() + "\'";
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" PROBLEMA Consultando categoria por codigo no obtuvo resultados");
                return null;
            }
            cat.setCodigoCategoria(rs.getString("codigo"));
            cat.setNombre(rs.getString("nombre"));
            cat.setCodigoUnidad(rs.getString("codigounidad"));
            System.out.println(query);
            return cat;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return cat;
    }

    public ArrayList<Categoria> consultarCategorias(Categoria categoria) {
        ArrayList<Categoria> result = new ArrayList<Categoria>();
        try {
            String query = " SELECT * from postgres.categoria  WHERE codigoUnidad ='" + categoria.getCodigoUnidad()
                    + "'";
            if (categoria.getNombre() != null && !categoria.getNombre().isEmpty()) {
                query += " AND nombre = '" + categoria.getNombre() + "'";
            }
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" PROBLEMA Consultando categoria por unidad no obtuvo resultados");
                return null;
            }
            System.out.println(query);
            while (rs.next()) {
                Categoria cat = new Categoria();
                cat.setCodigoCategoria(rs.getString("codigo"));
                cat.setNombre(rs.getString("nombre"));
                cat.setCodigoUnidad(rs.getString("codigounidad"));
                result.add(cat);
            }
            System.out.println(query);
            return result;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /*
     *
     * Metodos de matrices Descripcion una matriz que no tiene filas solo tiene
     * el esqueleto de sus columnas
     */
    public boolean agregarMatrizUnidad(Matriz m) {
        try {
            int agregadaMatriz = 0;
            Statement stmt = conexion.createStatement();
            String queryMatriz = "INSERT INTO postgres.matriz (nombre, fechacreacion, codigounidad) VALUES ";
            queryMatriz += "('" + m.getNombre() + "' , '" + m.getFechacreacion()
                    + "','" + m.getCodigoUnidad() + "')";
            agregadaMatriz = stmt.executeUpdate(queryMatriz);
            System.out.print(queryMatriz);
            String consultaMatriz = "SELECT * FROM postgres.matriz WHERE " + "nombre = '" + m.getNombre() + "'"
                    + "AND fechacreacion = " + "'" + m.getFechacreacion().toString() + "'"
                    + "AND codigounidad = " + "'" + m.getCodigoUnidad() + "'";
            System.out.println(queryMatriz);
            System.out.println(consultaMatriz);
            ResultSet rs = stmt.executeQuery(consultaMatriz);
            if (rs.next()) {
                m.setIdMatriz(rs.getInt("idmatriz"));
                m.setFechacreacion(rs.getString("fechacreacion"));
                Unidad u = new Unidad();
                u.setCodigo(m.getCodigoUnidad());
                ArrayList<Categoria> cat = this.consultarCategorias(u);
                m.setCategorias(cat);
                System.out.println("SE CREO BIEN EL OBJETO Y SE CONSULTO" + m.getIdMatriz());
            }
            return (agregadaMatriz > 0) && (m.getIdMatriz() != 0);
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * Agrega columnas a una matriz previamente agregada
     *
     * @param m
     * @return
     */
    public boolean agregarDescripcionMatriz(Matriz m) {
        try {
            int columnaAgregada = 0;
            for (Columna c : m.getColumnas()) {
                String queryColumna = "INSERT INTO postgres.columna (idmatriz , tipo , nombre, cpyd) VALUES "
                        + "('" + m.getIdMatriz() + "','"
                        + c.getTipo() + "','" + c.getNombre() + "', '" + c.guardarCpyd() + "')";
                System.out.println(queryColumna);
                Statement stmt = conexion.createStatement();
                columnaAgregada = stmt.executeUpdate(queryColumna);
                if (columnaAgregada < 0) {
                    eliminarMatriz(m);
                    return false;
                }
                String queryColumnaId = "SELECT idcolumna FROM postgres.columna WHERE idmatriz=" + m.getIdMatriz()
                        + " AND nombre='" + c.getNombre() + "'";
                stmt = conexion.createStatement();
                ResultSet rsColumna = stmt.executeQuery(queryColumnaId);
                if (rsColumna.next() && columnaAgregada > 0) {
                    c.setIdColumna(rsColumna.getInt("idcolumna"));
                } else {
                    return false;
                }
                System.out.println(queryColumnaId);
                if (c.getIdLista() > 0) {
                    boolean modificada = this.modificarColumna(c);
                    if (modificada) {
                        System.out.println("\t Se le agrego el idlista");
                    }
                }

            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }


        return true;
    }

    /*
     * Agregar a la base de datos filas a una matriz dependiendo de un formato
     * de columnas @param m @return
     */
    public boolean agregarFilas(Matriz m) {
        for (Celda f : m.getFilas()) {
            try {
                String queryFila = "INSERT INTO postgres.fila (idcolumna,nombre) VALUES"
                        + "(" + f.getIdColumna() + ",'" + f.getNombre() + "')";
                Statement stmt = conexion.createStatement();
                System.out.println(queryFila);
                int filaAgregada = stmt.executeUpdate(queryFila);
                if (filaAgregada < 0) {
                    return false;
                }

                String queryFilaId = "SELECT idfila FROM postgres.fila WHERE idcolumna = '" + f.getIdColumna() + "'"
                        + "AND nombre = '" + f.getNombre() + "'";
                stmt = conexion.createStatement();
                ResultSet rsFila = stmt.executeQuery(queryFilaId);
                if (rsFila.next() && filaAgregada > 0) {

                    f.setIdCelda(rsFila.getInt("idfila"));
                    System.out.println("  Inserto fila" + f.getIdCelda());
                } else {
                    return false;
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        return true;
    }

    public boolean eliminarFilas(Matriz m) {
        boolean right = false;
        String subm = "";

        try {
            int counter = 0;
            Statement stmt = conexion.createStatement();
            subm = m.getSubm();
            ArrayList<Columna> col = m.getColumnas();
            for (Columna c : col) {
                for (Celda cel : m.getFilas()) {
                    if (cel.getIdColumna().equals(c.getIdColumna())) {
                        if (Integer.valueOf(counter).toString().equals(subm)) {
                            String query = "DELETE FROM postgres.fila WHERE idfila = " + cel.getIdCelda();
                            int result = stmt.executeUpdate(query);
                            if (result == 0) {
                                return false;
                            }
                            counter = 0;
                            break;
                        } else {
                            counter++;
                        }
                    }

                }
            }
            right = true;
        } catch (SQLException sql) {
            System.err.println("Error de conexión en la bd(EliminarFilas)");
            return false;
        }


        return right;
    }
    /*
     * Leve cambio, eliminarMatriz retorna falso si no elimina la matriz y
     * verdadero si la elimina. Cambie eliminar matriz a public para que mi
     * action la pudiera usar.
     */

    public boolean eliminarMatriz(Matriz m) {
        m = this.consultarMatriz(m);
        try {
            int columnaBorrada = 0;
            for (Columna c : m.getColumnas()) {

                int filaBorrada = 0;
                for (Celda f : m.getFilas()) {
                    if (f.getIdColumna().equals(c.getIdColumna())) {
                        String borrarFila = "DELETE FROM postgres.fila WHERE idcolumna = "
                                + f.getIdColumna();
                        Statement stmtFila = conexion.createStatement();
                        filaBorrada += stmtFila.executeUpdate(borrarFila);
                        System.out.println(borrarFila);
                    }
                    if (filaBorrada < m.getFilas().size()) {
                        System.out.println("NO SE ELIMINARON TODAS LAS FILAS");
                    }
                    Statement stmtColumna = conexion.createStatement();
                    String borrarColumnas = "DELETE  FROM postgres.columna WHERE idmatriz =" + m.getIdMatriz();
                    columnaBorrada += stmtColumna.executeUpdate(borrarColumnas);

                    System.out.println(borrarColumnas);
                }
                if (columnaBorrada < m.getColumnas().size()) {
                    System.out.println("NO SE ELIMINARON TODAS LAS COLUMNAS");
                }
            }

            Statement stmt = conexion.createStatement();
            String borrarMatriz = "DELETE  FROM postgres.matriz WHERE idmatriz = " + m.getIdMatriz();
            stmt = conexion.createStatement();
            System.out.print(borrarMatriz + "\n");
            int matrizBorrada = stmt.executeUpdate(borrarMatriz);
            if (matrizBorrada < 0) {
                System.out.print("NO SE ELIMINO CORRECTAMENTE");
                return false;
            }

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return true;
    }

    public ArrayList<Matriz> consultarMatrices() {
        try {
            System.out.println("Entrando a consultar todas las matrices");
            String query = "Select * from postgres.matriz";
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            ArrayList<Matriz> matrices = new ArrayList<Matriz>();
            while (rs.next()) {
                Matriz m = new Matriz();
                m.setCodigoUnidad(rs.getString("codigoUnidad"));
                m.setFechacreacion(rs.getString("fechacreacion"));
                m.setNombre(rs.getString("nombre"));
                m.setIdMatriz(rs.getInt("idmatriz"));
                matrices.add(m);
                System.out.println("Agregando matrices" + m.getNombre() + m.getFechacreacion());
            }
            return matrices;


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public ArrayList<Matriz> consultarMatricesPorUnidad(String codigoUnidad) {
        try {
            System.out.println("Entrando a consultar algunas matrices");
            String query = "Select * from postgres.matriz WHERE codigounidad='" + codigoUnidad + "'";
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            ArrayList<Matriz> matrices = new ArrayList<Matriz>();
            while (rs.next()) {
                Matriz m = new Matriz();
                m.setCodigoUnidad(rs.getString("codigoUnidad"));
                m.setFechacreacion(rs.getString("fechacreacion"));
                m.setNombre(rs.getString("nombre"));
                m.setIdMatriz(rs.getInt("idmatriz"));
                matrices.add(m);
                System.out.println("Agregando matrices" + m.getNombre() + m.getFechacreacion());
            }
            return matrices;


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public Matriz consultarMatrizConDatos(Matriz matriz, String ano, String trimestre) {
        try {
            String query = " SELECT * from postgres.matriz  WHERE idmatriz = " + matriz.getIdMatriz();
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" No se obtuvieron resultados ");
                return null;
            }
            matriz.setNombre(rs.getString("nombre"));
            matriz.setFechacreacion(rs.getString("fechacreacion"));
            matriz.setCodigoUnidad(rs.getString("codigounidad"));

            // Buscamos las columnas de la matriz
            ArrayList<Columna> columnas = consultarColumnas(matriz);

            ArrayList<Celda> celdas = new ArrayList<Celda>();

            for (Columna columna : columnas) {
                ArrayList<Celda> fil = consultarFilas(columna);

                for (Celda celda : fil) {
                    if (!columna.guardarCpyd()) {
                        Dato d = consultarDato(celda, matriz.getTipo(), ano, trimestre);
                        if (d != null) {
                            celda.setDato(d);
                            celda.setIdDato(d.getId());
                        }
                    }
                    celdas.add(celda);
                }

            }

            //Ordenamos las filas segun su idfila
            Collections.sort(celdas, new Comparator<Celda>() {

                @Override
                public int compare(Celda fila1, Celda fila2) {
                    return fila1.getIdCelda() - fila2.getIdCelda();
                }
            });

            matriz.setColumnas(columnas);
            matriz.setFilas(celdas);

            ArrayList<Lista> listas = DataBaseManager.getInstance().consultarListas();
            for (Columna col : matriz.getColumnas()) {
                if ("Lista".equals(col.getTipo())) {
                    for (Lista lista : listas) {
                        if (lista.getIdLista() == (col.getIdLista())) {
                            col.setLista(lista);
                        }
                    }
                }
            }
            return matriz;

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return matriz;
    }

    /**
     * Obtiene todas las columnas, filas de la Matriz matriz Sin datos
     * especificos.
     *
     * @param matriz
     * @return Matriz con toda la informacion
     */
    public Matriz consultarMatriz(Matriz matriz) {
        try {
            String query = " SELECT * from postgres.matriz  WHERE idmatriz = " + matriz.getIdMatriz();
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" No se obtuvieron resultados ");
                return null;
            }
            matriz.setNombre(rs.getString("nombre"));
            matriz.setFechacreacion(rs.getString("fechacreacion"));
            matriz.setCodigoUnidad(rs.getString("codigounidad"));

            // Buscamos las columnas de la matriz
            ArrayList<Columna> columnas = consultarColumnas(matriz);

            ArrayList<Celda> celdas = new ArrayList<Celda>();

            for (Columna columna : columnas) {
                ArrayList<Celda> fil = consultarFilas(columna);

                for (Celda celda : fil) {
                    if (!columna.guardarCpyd()) {
                        celda.setDato(new Dato());
                    }
                    celdas.add(celda);
                }
            }

            //Ordenamos las filas segun su idfila
            Collections.sort(celdas, new Comparator<Celda>() {

                @Override
                public int compare(Celda fila1, Celda fila2) {
                    return fila1.getIdCelda() - fila2.getIdCelda();
                }
            });

            matriz.setColumnas(columnas);
            matriz.setFilas(celdas);

            ArrayList<Lista> listas = DataBaseManager.getInstance().consultarListas();
            for (Columna col : matriz.getColumnas()) {
                if ("Lista".equals(col.getTipo())) {
                    for (Lista lista : listas) {
                        if (lista.getIdLista() == (col.getIdLista())) {
                            col.setLista(lista);
                        }
                    }
                }
            }
            return matriz;

        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return matriz;
    }

    public ArrayList<Columna> consultarColumnas(Matriz m) {
        try {
            System.out.println("ConsultarColumnas (BD) ");
            System.out.println("Matriz" + m.getIdMatriz());
            String query = "Select * from postgres.columna WHERE idmatriz = " + m.getIdMatriz();
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            ArrayList<Columna> columnas = new ArrayList<Columna>();
            while (rs.next()) {
                Columna col = new Columna();
                col.setNombre(rs.getString("nombre"));
                col.setIdColumna(rs.getInt("idcolumna"));
                col.setTipo(rs.getString("tipo"));
                col.isCpyd(rs.getBoolean("cpyd"));
                col.setIdLista(rs.getInt("idlista"));

                columnas.add(col);

            }
            System.out.println("Agregada columnas de: " + m.getNombre());
            return columnas;

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public ArrayList<Celda> consultarFilas(Columna columna) {
        try {
            System.out.println("ConsultarFilas (BD) ");

            String query = "Select * from postgres.fila WHERE idcolumna = " + columna.getIdColumna();
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            ArrayList<Celda> filas = new ArrayList<Celda>();
            while (rs.next()) {
                Celda fil = new Celda();
                fil.setNombre(rs.getString("nombre"));
                fil.setIdColumna(rs.getInt("idcolumna"));
                fil.setIdCelda(rs.getInt("idfila"));
                filas.add(fil);

            }
            System.out.println("Consultada las filas columna " + columna.getNombre());
            return filas;

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public boolean modificarFila(Celda f) {
        int modificado = 0;
        try {
            Connection c = DataBaseManager.conexion;
            Statement s = c.createStatement();

            if (f.getIdCelda() == null) {
                return false;
            }
            String query = "Update fila\n set nombre = '"
                    + f.getNombre() + "' where idfila=" + f.getIdCelda();
            modificado = s.executeUpdate(query);
            System.out.println(query);


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return modificado > 0;

    }

    public boolean modificarColumna(Columna col) {
        int modificado = 0;
        try {
            Connection c = DataBaseManager.conexion;
            Statement s = c.createStatement();

            if (col.getIdColumna() == null) {
                return false;
            }
            String query = "Update columna\n set idlista ="
                    + col.getIdLista() + " where idcolumna=" + col.getIdColumna();
            modificado = s.executeUpdate(query);
            System.out.println(query);

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return modificado > 0;

    }

    /**
     * Agrega un dato a la base de datos con la informacion de d
     *
     * @param d
     * @return true si fue exitoso, en otro caso, false.
     */
    public boolean agregarDato(Dato d) {
        int agregado = 0;
        try {
            String query = "";
            if (d.getTipo().equals("Ajuste")) {
                query = "INSERT INTO postgres.dato (fecha,idfila,valor,tipo,incremento) VALUES "
                        + "('" + d.getFecha() + "','" + d.getFilaId() + "','" + d.getValor() + "','" + d.getTipo() + "',"
                        + d.isIncremento() + ")";
            } else {
                query = "INSERT INTO postgres.dato (fecha,idfila,valor,tipo) VALUES "
                        + "('" + d.getFecha() + "','" + d.getFilaId() + "','" + d.getValor() + "','" + d.getTipo() + "')";
            }
            System.out.println(query);
            Statement stmt = conexion.createStatement();
            agregado = stmt.executeUpdate(query);

            if (agregado > 0) {
                String select = "SELECT iddato from postgres.dato WHERE idfila=" + d.getFilaId() + " "
                        + "AND fecha='" + d.getFecha() + "' AND tipo='" + d.getTipo() + "'";
                ResultSet rs = stmt.executeQuery(select);
                if (rs.next()) {
                    d.setId(rs.getInt("iddato"));
                }
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return agregado > 0;
    }

    /**
     * Obtiene toda la informacion del dato mas reciente que esta asociado a la
     * celda f. Se debe especificar el tipo de dato que se quiere consultar
     *
     * @param f
     * @param tipo: puede ser planificacion, ajuste o ejecucion
     * @return Dato con toda su informacion asociada.
     */
    public Dato consultarDato(Celda f, String tipo, String ano, String trimestre) {

        try {
            Statement stmt = conexion.createStatement();
            String select = "SELECT * from postgres.dato WHERE idfila=" + f.getIdCelda() + " AND tipo='" + tipo + "' ORDER BY fecha,iddato DESC";
            ResultSet rs = stmt.executeQuery(select);
            System.out.println("Consultar Dato: " + select);
            Dato d = new Dato();

            if (rs.next()) {

                String fecha = rs.getString("fecha");
                if (ano.equals(this.extraerAno(fecha))) {
                    if (tipo.equals("Ajuste") || tipo.equals("Ejecucion")) {
                        if (trimestre.equals(this.extraerTrimestre(fecha))) {
                            d.setId(rs.getInt("iddato"));
                            d.setFilaId(rs.getInt("idfila"));
                            d.setValor(rs.getString("valor"));
                            d.setFecha(rs.getString("fecha"));
                            d.setIncremento(rs.getBoolean("incremento"));
                        }
                    } else { // Si es planificacion
                        d.setId(rs.getInt("iddato"));
                        d.setFilaId(rs.getInt("idfila"));
                        d.setValor(rs.getString("valor"));
                        d.setFecha(rs.getString("fecha"));
                        d.setIncremento(rs.getBoolean("incremento"));
                    }

                }

                return d;
            }


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * Numero de ejecuciones que se han realizado hasta la fecha
     *
     * @param dato: dato de la celda.
     * @return int numero de entradas para la ejecucion en un año especifico
     */
    public int cantidadEjecucion(Dato dato) {
        int cantidadEjecucion = 0;
        try {
            Statement stmt = conexion.createStatement();
            String select = "SELECT * from postgres.dato WHERE idfila=" + dato.getFilaId() + " AND tipo='" + dato.getTipo() + "' ORDER BY fecha DESC";
            ResultSet rs = stmt.executeQuery(select);
            System.out.println("QUERY " + select);
            while (rs.next()) {
                String fecha[] = rs.getString("fecha").split("/");
                String ano = fecha[0];
                String fechaDato[] = dato.getFecha().split("/");
                System.out.println("Ano y fechaDato " + ano + " " + fechaDato[0]);
                if (fechaDato[0].equals(ano)) {
                    cantidadEjecucion++;
                    System.out.println("CantidadEjecuion " + cantidadEjecucion);
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return cantidadEjecucion;
    }
//    public boolean modificarDato(Dato d) {
//        int modificado = 0;
//        try {
//            Connection c = DataBaseManager.conexion;
//            Statement s = c.createStatement();
//            if (d.getValorPlanificacion() != null) {
//                String query = "Update dato\n set valorplanificacion = '"
//                        + d.getValorPlanificacion() + "' where iddato=" + d.getId();
//                modificado = s.executeUpdate(query);
//                System.out.println(query);
//            }
//            if (d.getValorAjuste() != null) {
//                String query = "Update dato\n set valorajuste = '"
//                        + d.getValorAjuste() + "' where iddato=" + d.getId();
//                modificado = s.executeUpdate(query);
//                System.out.println(query);
//            }
//            if (d.getValorEjecucion() != null) {
//                String query = "Update dato\n set valorejecucion = '"
//                        + d.getValorEjecucion() + "' where iddato=" + d.getId();
//                modificado = s.executeUpdate(query);
//                System.out.println(query);
//            }
//
//
//        } catch (SQLException ex) {
//            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        return modificado > 0;
//    }

//    private boolean agregarRelacionCategoria(Matriz m) {
//        try {
//            int categoriaAgregada = 0;
//            if (m.getCategorias() == null) {
//                Unidad u = new Unidad();
//                u.setCodigo(m.getCodigoUnidad());
//                m.setCategorias(this.consultarCategorias(u));
//            }
//            for (Categoria cat : m.getCategorias()) {
//                String queryCategoria = "INSERT INTO postgres.matrizcategoria (idmatriz,idcategoria) VALUES "
//                        + "(" + m.getIdMatriz() + ",'" + cat.getCodigoCategoria() + "'" + ")";
//                Statement stmt = conexion.createStatement();
//                categoriaAgregada = stmt.executeUpdate(queryCategoria);
//                System.out.println(queryCategoria);
//                if (categoriaAgregada < 0) {
//                    eliminarMatriz(m);
//                    return false;
//                }
//            }
//            return categoriaAgregada > 0;
//
//
//        } catch (SQLException ex) {
//            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        return false;
//    }
    public boolean agregarLista(Lista l) {
        try {
            String query = "INSERT INTO postgres.lista (nombre) VALUES ('" + l.getNombre() + "')";
            int agregada = 0;
            Statement stmt = conexion.createStatement();
            agregada = stmt.executeUpdate(query);
            if (agregada > 0) {
                String queryConsulta = "SELECT idlista FROM postgres.lista WHERE nombre = '" + l.getNombre() + "'";
                stmt = conexion.createStatement();
                ResultSet rs = stmt.executeQuery(queryConsulta);
                if (rs.next()) {
                    System.out.println("(BD): Se guardo la lista con ID :" + rs.getInt("idlista"));
                    l.setIdLista(rs.getInt("idlista"));
                }
            }
            System.out.println(query);
            return agregada > 0;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public boolean agregarValores(Lista l) {
        try {
            String query = "INSERT INTO postgres.listavalor (idlista,valor) VALUES ";
            boolean valoresAgregados = true;
            for (Valor valor : l.getValores()) {
                System.out.println("intentando agregar valor " + valor.getValor());
                Statement stmt = conexion.createStatement();
                int valorAgregado;
                String query2 = query + "(" + l.getIdLista() + ",'" + valor.getValor() + "')";
                valorAgregado = stmt.executeUpdate(query2);
                System.out.println(query2);
                valoresAgregados = valoresAgregados && (valorAgregado > 0);
            }


            return valoresAgregados;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public ArrayList<Lista> consultarListas() {
        ArrayList<Lista> listas = new ArrayList<Lista>();
        try {
            String query = "SELECT * FROM postgres.lista";
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                Lista l = new Lista();
                l.setIdLista(rs.getInt("idlista"));
                l.setNombre(rs.getString("nombre"));
                l.setValores(this.consultarValores(l));
                listas.add(l);
            }
            System.out.println("RETORNANDO LISTAS");
            return listas;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return listas;
    }

    private ArrayList<Valor> consultarValores(Lista l) {
        try {
            ArrayList<Valor> valores = new ArrayList<Valor>();
            String query = "SELECT valor FROM postgres.listavalor WHERE idlista =" + l.getIdLista();
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);

            System.out.println(query);
            while (rs.next()) {
                valores.add(new Valor(rs.getString("valor")));
            }
            return valores;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public boolean eliminarLista(Lista l) {
        try {
            int eliminado = 0;
            String queryDepend = "DELETE FROM postgres.listavalor WHERE idlista=" + l.getIdLista();
            String query = "DELETE FROM postgres.lista WHERE idlista =" + l.getIdLista();
            Statement stmt = conexion.createStatement();
            eliminado = stmt.executeUpdate(queryDepend);
            stmt = conexion.createStatement();
            System.out.println(queryDepend);
            System.out.println(query);
            eliminado = eliminado + (stmt.executeUpdate(query));
            return eliminado >= 1;
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    /**
     * REPORTES *
     */
    /**
     * Agrega el Reporte recibido a la base de datos
     *
     * @param r : Reporte
     * @return int : mayor de 0, exitoso.
     */
    public int agregarReporte(Reporte r) {
        int agregado = 0;
        try {

            System.out.println("BD: Agregar Reporte: " + r.getNombre());
            Statement stmt = conexion.createStatement();
            String query = "INSERT INTO postgres.reporte (nombre, fechacreacion) VALUES ";
            query += "('" + r.getNombre() + "' , '" + r.getFechaCreacion() + "')";
            agregado = stmt.executeUpdate(query);
            System.out.println(query);
            String consulta = "SELECT * FROM postgres.reporte WHERE " + "nombre = '" + r.getNombre() + "'"
                    + "AND fechacreacion = " + "'" + r.getFechaCreacion().toString() + "'";

            ResultSet rs = stmt.executeQuery(consulta);
            if (rs.next()) {
                r.setIdreporte(rs.getInt("idreporte"));
                r.setFechaCreacion(rs.getString("fechacreacion"));
                r.setPublico(true);
            }
            System.out.println("BD idreporte" + r.getIdreporte());
            return agregado;
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return agregado;
    }

    /**
     * Consultar todos los reportes existentes
     *
     * @return ArrayList<Reporte>
     */
    public ArrayList<Reporte> consultarReportes() {
        try {
            System.out.println("BD: Consultar Reportes");
            String query = "Select * from postgres.reporte";
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            ArrayList<Reporte> reportes = new ArrayList<Reporte>();
            while (rs.next()) {
                Reporte r = new Reporte();

                r.setFechaCreacion(rs.getString("fechacreacion"));
                r.setNombre(rs.getString("nombre"));
                r.setIdreporte(rs.getInt("idreporte"));
                reportes.add(r);
                System.out.println("Agregando reporte:" + r.getNombre() + r.getFechaCreacion());
            }
            return reportes;


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public ArrayList<Reporte> consultarReportesAno(int ano, int trimestre) {
        ArrayList<Reporte> reportes = new ArrayList<Reporte>();

        return reportes;
    }

    /**
     * Agregar matriz a un reporte La matriz mat recibida es anadida al reporte
     * r
     *
     * @param mat
     * @param r
     * @return true de ser correcta la ejecucion, false si falla
     */
    public boolean agregarMatrizReporte(Matriz mat, Reporte r) {
        try {

            String query = "INSERT INTO postgres.matricesreporte(idrep,idmatriz) VALUES ("
                    + r.getIdreporte() + " , " + mat.getIdMatriz() + ")";

            Statement stmt = conexion.createStatement();
            System.out.println(query);
            int agregado = stmt.executeUpdate(query);
            return agregado > 0;

        } catch (SQLException ex) {
            System.out.println("Error: agregarMatrizReporte");
        }
        return false;
    }

    /**
     * Agrega una totalizacion a un reporte. Precondicion: El reporte debe
     * contener a la matriz a la cual la totalizacion a agregar esta asociada.
     *
     * @param t : Totalizacion a agregar
     * @param r : Reporte a modificar
     * @return
     */
    public boolean agregarReporteTotalizacion(Totalizacion t, Reporte r) {
        try {
            String query = "INSERT INTO postgres.reptotalizacion(idrep,idtotalizacion) VALUES ("
                    + r.getIdreporte() + " , " + t.getIdTotalizacion() + ")";
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            int agregado = stmt.executeUpdate(query);
            return agregado > 0;

        } catch (SQLException ex) {
            System.out.println("Error DBMS: agregar totalizacion en reporte");
        }
        return false;
    }

    /**
     * Consulta la informacion del reporte que recibe
     *
     * @param r: Reporte
     * @return Reporte con toda la informacion de la tabla.
     */
    public Reporte consultarReporte(Reporte r) {
        try {
            String query = " SELECT * from postgres.reporte  WHERE idreporte = " + r.getIdreporte();
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (rs.next()) {
                r.setNombre(rs.getString("nombre"));
                r.setFechaCreacion(rs.getString("fechacreacion"));
                r.setIdreporte(rs.getInt("idreporte"));
            }
            return r;
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * Este metodo devuelve todas las matrices (por ahora) del reporte que
     * recibe.
     *
     * @param r : Reporte
     * @return ArrayList<Reportable>
     */
    public ArrayList<Reportable> consultarElementosReporte(Reporte r) {
        ArrayList<Reportable> elementos = new ArrayList<Reportable>();
        try {
            String query = " SELECT * from postgres.matricesreporte WHERE idrep = " + r.getIdreporte();
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            System.out.println(query);

            while (rs.next()) {
                System.out.println("Hay resultado");
                Matriz m = new Matriz();
                m.setIdMatriz(rs.getInt("idmatriz"));
                m = this.consultarMatriz(m);


                System.out.println("BD: Ajusto plan, ajuste, ejec" + rs.getBoolean("plan") + " " + rs.getBoolean("ajuste") + " " + rs.getBoolean("ejec"));
                m.setPlan(rs.getBoolean("plan"));


                m.setAjuste(rs.getBoolean("ajuste"));


                m.setEjec(rs.getBoolean("ejec"));

                m.setIdReporte(rs.getInt("idrep"));
                elementos.add(m);
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return elementos;
    }

    /**
     * Este metodo permite actualizar en la tabla matrices-reporte los booleanos
     * "planificacion", "ajuste", "ejecucion"
     *
     * @param m : Matriz
     * @return boolean : true exitoso, false si no.
     */
    public boolean modificarMatrizReporte(Matriz m, Reporte r) {
        int modificado = 0;
        try {

            Statement stmt = DataBaseManager.conexion.createStatement();
            String query = "Update matricesreporte \n set plan = " + m.isPlan() + ", "
                    + "ajuste = " + m.isAjuste() + ", ejec =" + m.isEjec() + " WHERE idrep=" + r.getIdreporte()
                    + " AND idmatriz=" + m.getIdMatriz();
            System.out.println(query);
            modificado = stmt.executeUpdate(query);
        } catch (SQLException ex) {
            System.out.println("Error SQL: modificarMatrizReporte");
        }
        return modificado > 0;
    }

    /**
     * Eliminar reporte recibido
     *
     * @param
     */
    public boolean eliminarReporte(Reporte r) {
        int eliminado = 0;
        try {

            Statement stmt = DataBaseManager.conexion.createStatement();
            String query = "Delete from postgres.reporte WHERE idreporte=" + r.getIdreporte();
            eliminado = stmt.executeUpdate(query);

            System.out.println(query + "    " + eliminado);
            //Procedo a eliminar las entradas en matricesreporte
            this.eliminarMatricesReporte(r);

        } catch (SQLException ex) {
            System.out.println("Error: eliminarReporte");
        }
        return eliminado > 0;
    }

    /**
     * Eliminar las relaciones entre el reporte a eliminar y las matrices.
     *
     * @param r : Reporte
     * @return boolean: true si exitoso, false si no.
     */
    public boolean eliminarMatricesReporte(Reporte r) {
        int eliminado = 0;
        try {

            Statement stmt = DataBaseManager.conexion.createStatement();
            String query = "Delete from postgres.matricesreporte WHERE idrep=" + r.getIdreporte();
            eliminado = stmt.executeUpdate(query);
            System.out.println(query + "    " + eliminado);
            //Procedo a eliminar las entradas en matricesreporte
        } catch (SQLException ex) {
            System.out.println("Error: eliminarMatricesReporte");
        }
        return eliminado > 0;
    }

    public boolean modificarMatriz(Matriz m) {
        int i = 0;
        Celda c1 = null;
        boolean datosMod = false;
        ArrayList<Columna> columnas = m.getColumnas();
        int colSize = columnas.size();
        int filSize = m.getFilas().size();
        int cociente = filSize / colSize;
        int cantMod = 0;
        for (Columna c : columnas) {
            ArrayList<Celda> ac = consultarFilas(c);
            for (Celda cel : ac) {
                boolean test = false;
                while (!test) {
                    if (i % colSize == cantMod) {
                        c1 = (Celda) m.getFilas().get(i);
                        test = true;
                    }
                    i++;
                }
                c1.setIdCelda(cel.getIdCelda());
                datosMod = modificarFila(c1);
                System.out.println("Fila modificada: " + datosMod);

            }
            i = 0;
            cantMod++;
        }
        return datosMod;
    }

    /**
     * *******************************************************************
     *********** CONJUNTO DE OPERACIONES SOBRE TOTALIZACIONES ************
     * *******************************************************************
     */
    /**
     *
     * @param t Totalizacion a ser agregada a la base de datos.
     * @return True si se agrego adecuadamente la totalizacion, False en caso
     * contrario.
     */
    public boolean agregarTotalizacion(Totalizacion t) {

        Connection connection = DataBaseManager.conexion;
        int resultado = 0;
        try {
            System.out.println("Totalizacion nombre idmatriz" + t.getNombre() + " " + t.getIdMatriz());
            Statement st = connection.createStatement();
            String query = "INSERT INTO postgres.totalizacion(nombre, idmatriz) VALUES ('" + t.getNombre() + "' , " + t.getIdMatriz() + ")";
            resultado = st.executeUpdate(query);

            String select = "SELECT * FROM postgres.totalizacion WHERE nombre ='" + t.getNombre() + "' AND idmatriz =" + t.getIdMatriz();
            ResultSet rst = st.executeQuery(select);
            System.out.println("Hice el resultset");

            if (rst.next()) {
                t.setIdTotalizacion(rst.getInt("idtotalizacion"));
                System.out.println("Id totalizacion en BD" + t.getIdTotalizacion());
            }

        } catch (SQLException sqle) {
            System.out.println("Error agregando totalizacion.");
            return false;
        }

        for (Celda c : t.getCeldasATotalizar()) {
            try {
                System.out.println("CeldaATotalizar " + c.getIdCelda());
                System.out.println("Id totalizacion en BD" + t.getIdTotalizacion());
                Statement st = connection.createStatement();
                String insert = "INSERT INTO postgres.celdatotalizacion (idtotalizacion, idfila) VALUES (" + t.getIdTotalizacion() + " , " + c.getIdCelda() + ")";
                st.executeUpdate(insert);
                System.out.println(insert);
            } catch (SQLException sqle) {
                System.out.println("Error agregando celda totalizacion.");
                return false;
            }
        }
        return resultado > 0;
    }

    /**
     * Consulta Totalizacion
     *
     * @param t
     * @return
     */
    public Totalizacion consultarTotalizacion(Totalizacion t) {
        try {
            //Establecemos la conexion a la base de datos.
            Connection c = DataBaseManager.conexion;

            //En un principio, sacaremos los datos de la totalizacion que estan
            //asociados al id de matriz que fue recibido en la entrada.
            String query = "select * from postgres.totalizacion where idmatriz=" + t.getIdMatriz() + " AND nombre='" + t.getNombre() + "'";
            Statement st = c.createStatement();

            ResultSet rst = st.executeQuery(query);

            //Creo nuevos objetos Totalizacion con los datos de cada uno de los
            //elementos contenidos en el resultado del query ejecutado.
            if (rst.next()) {
                System.out.println("Matriz+" + t.getIdMatriz());
                t.setIdMatriz(t.getIdMatriz());
                Matriz m = new Matriz();
                m.setIdMatriz(t.getIdMatriz());
                t.setMatriz(this.consultarMatriz(m));
                t.setIdTotalizacion(rst.getInt("idtotalizacion"));
                t.setNombre(rst.getString("nombre"));

            } else {
                return null;
            }
            return t;
        } catch (SQLException sqle) {
            System.out.println("Error al intentar consultar las totalizaciones"
                    + "de la matriz");
            return null;
        }
    }

    /**
     * Metodo que recibe una totalizacion, el ano, trimestre y tipo de la matriz
     * a totalizar y devuelve las celdas con los datos correspondientes
     *
     * @param t : Totalizacion
     * @param tipo : Tipo (Planificacion, Ajuste, Ejecucion)
     * @param ano : Ano del dato
     * @param trimestre : Trimestre del dato
     * @return
     */
    public Totalizacion obtenerCeldasTotalizacion(Totalizacion t, String tipo, String ano, String trimestre) {
        try {
            Connection c = DataBaseManager.conexion;
            Statement st = c.createStatement();
            ArrayList<Celda> celdasTotalizacion = new ArrayList<Celda>();

            String query = "select f.nombre, d.valor, d.fecha "
                    + "from postgres.celdatotalizacion as c, dato as d, fila as f "
                    + "where (c.idtotalizacion=" + t.getIdTotalizacion().toString()
                    + " and c.idfila = f.idfila and f.idfila = d.idfila and d.tipo='" + tipo + "')";

            //Obtendre el nombre de la celda y el valor del dato en dicha celda para
            //cada una de las celdas involucradas en la totalizacion.
            ResultSet celdas = st.executeQuery(query);
            System.out.println(query);

            while (celdas.next()) {
                Celda celda = new Celda();
                Dato d = new Dato();
                String fechaDato = celdas.getString("fecha");
                // Para cada celda, revisar si esta en el ano y trimestre adecuado
                boolean trimValido = true;
                if (!trimestre.equals("0") && !tipo.equals("Planificacion")) { //Esto, porque en Programacion puede que no haya trimestre
                    trimValido = trimestre.equals(this.extraerTrimestre(fechaDato));
                }
                System.out.println("Dato: Valor, Fecha" + celdas.getString("valor") + " " + fechaDato);
                System.out.println("Ano y trim pasado por parametro " + ano + " " + trimestre);
                System.out.println("this.extraerAno de la fechaDato" + this.extraerAno(fechaDato));
                if (ano.equals(this.extraerAno(fechaDato)) && trimValido) {
                    d.setValor(celdas.getString("valor"));

                    //Fijo el dato.
                    celda.setDato(d);

                    //Fijo el nombre.
                    celda.setNombre(celdas.getString("nombre"));

                    celdasTotalizacion.add(celda);
                }
            } //fin while

            t.setCeldasATotalizar(celdasTotalizacion);
            return t;
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

//   /**
//    * 
//    * @param t
//    * @return 
//    */
//    public ArrayList<Totalizacion> consultarTotalizacion(Integer idMatriz) {
//        try {
//            //Establecemos la conexion a la base de datos.
//            Connection c = DataBaseManager.conexion;
//            
//            //En un principio, sacaremos los datos de la totalizacion que estan
//            //asociados al id de matriz que fue recibido en la entrada.
//            String query = "select * from postgres.totalizacion where idmatriz=" + idMatriz.toString();
//            Statement st = c.createStatement();
//            
//            ArrayList<Totalizacion> totalizaciones = new ArrayList<Totalizacion>();
//            
//            ResultSet rst = st.executeQuery(query);
//            
//            //Creo nuevos objetos Totalizacion con los datos de cada uno de los
//            //elementos contenidos en el resultado del query ejecutado.
//            while(rst.next()) {
//                
//                //Creo el nuevo objeto Totalizacion...
//                Totalizacion t = new Totalizacion();
//                
//                ArrayList<Celda> celdasTotalizacion = new ArrayList<Celda>();
//                t.setIdMatriz(idMatriz);
//                t.setIdTotalizacion(rst.getInt("idtotalizacion"));
//                t.setNombre(rst.getString("nombre"));
//                
//                query = "select valor from postgres.celdatotalizacion join postgres.dato "
//                        + "where idtotalizacion=" + t.getIdTotalizacion().toString();
//                ResultSet celdas = st.executeQuery(query);
//                
//                while(celdas.next()) {
//                    Celda celda = new Celda();
//                    Dato d = new Dato();
//                    d.setValor(celdas.getString("valor"));
//                    celda.setDato(d);
//                    
//                    celdasTotalizacion.add(celda);
//                }
//                
//                t.setCeldasATotalizar(celdasTotalizacion);
//            }
//            
//            return totalizaciones;
//        } catch (SQLException sqle) {
//            System.out.println("Error al intentar consultar las totalizaciones"
//                    + "de la matriz");
//            return null;
//        }
//    }
//    
    public ArrayList<Totalizacion> consultarTotalizaciones(Integer idMatriz) {
        Connection c = DataBaseManager.conexion;
        ArrayList<Totalizacion> totalizaciones = new ArrayList<Totalizacion>();

        try {
            String query = "select * from totalizacion where idmatriz=" + idMatriz.toString();
            Statement st = c.createStatement();
            ResultSet rst = st.executeQuery(query);

            while (rst.next()) {
                Totalizacion t = new Totalizacion();
                t.setIdMatriz(idMatriz);
                t.setNombre(rst.getString("nombre"));
                t.setIdTotalizacion(rst.getInt("idtotalizacion"));
                totalizaciones.add(t);
            }

        } catch (SQLException sqle) {
            System.out.println("Error al intentar consultar las totalizaciones"
                    + "de la matriz");
            return null;
        }
        return totalizaciones;
    }

    /**
     * Funcion que elimina una totalizacion de la base de datos.
     *
     * @param t Totalizacion que sera eliminada.
     * @return True si se logro eliminar exitosamente. False en caso contrario.
     */
    public boolean eliminarTotalizacion(Totalizacion t) {

        try {
            Connection c = DataBaseManager.conexion;
            Statement st = c.createStatement();
            st.executeUpdate("delete * from postgres.totalizacion where idtotalizacion = '" + t.getIdTotalizacion() + "'");
        } catch (SQLException sqle) {
            System.out.println("Error al eliminar totalizacion.");
            return false;
        }

        return true;
    }

    /**
     * Metodo para consultar todas las totalizaciones, su informacion basica
     * Retorna el nombre y el id de la totalizacion
     *
     * @return Coleccion de las totalizaciones
     */
    public ArrayList<Totalizacion> consultarTodasTotalizaciones() {
        ArrayList<Totalizacion> totalizaciones = new ArrayList<Totalizacion>();
        try {

            String query = "Select idtotalizacion, nombre FROM postgres.totalizacion";
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                Totalizacion totalizacion = new Totalizacion();
                totalizacion.setIdTotalizacion(rs.getInt("idtotalizacion"));
                totalizacion.setNombre(rs.getString("nombre"));
                totalizaciones.add(totalizacion);
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return totalizaciones;
    }

    /**
     * Consultar Totalizacion (nombre)
     *
     * @param u
     */
    public Totalizacion consultarTotalizacionPorNombre(String nombre) {
        Totalizacion totalizacion = null;
        try {

            String query = "Select * FROM postgres.totalizacion WHERE nombre= '" + nombre.toString() + "'";
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                if (totalizacion == null) {
                    totalizacion = new Totalizacion();
                }
                totalizacion.setIdTotalizacion(rs.getInt("idtotalizacion"));
                totalizacion.setNombre(rs.getString("nombre"));
                totalizacion.setIdMatriz(rs.getInt("idmatriz"));

            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return totalizacion;

    }

    /**
     * Consultar Totalizacion (IdTotalizacion)
     *
     * @param u
     */
    public Totalizacion consultarTotalizacionPorId(Integer idtotalizacion) {
        Totalizacion totalizacion = new Totalizacion();
        try {

            String query = "Select * FROM postgres.totalizacion WHERE idtotalizacion=" + idtotalizacion;
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                totalizacion.setIdTotalizacion(rs.getInt("idtotalizacion"));
                totalizacion.setNombre(rs.getString("nombre"));
                totalizacion.setIdMatriz(rs.getInt("idmatriz"));
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return totalizacion;

    }

    public void modificarPermiso(Usuario u) {
        String sqlquery = "UPDATE postgres.usuario SET ";
        sqlquery += "permiso = " + "'" + u.getPermiso() + "'" + " WHERE usuario =" + "'" + u.getUsuario() + "'";
        Statement stmt;
        int modificado = 0;
        try {
            stmt = conexion.createStatement();
            System.out.println(sqlquery);
            modificado = stmt.executeUpdate(sqlquery);
            DataBaseManager.sincronizarUsuarios();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        if (modificado == 0) {
            System.out.println("No se modifico el permiso");
        }
    }

    public void eliminarPermiso(Usuario u) {
        String sqlquery = "UPDATE  postgres.usuario SET ";
        sqlquery += "permiso = " + "'" + "No asignado" + "'" + " WHERE usuario =" + "'" + u.getUsuario() + "'";
        int modificado;
        try {
            Statement stmt = conexion.createStatement();
            modificado = stmt.executeUpdate(sqlquery);
            System.out.println(sqlquery);
            DataBaseManager.sincronizarUsuarios();
            if (modificado > 0) {
                System.out.println("Permiso Modificado");
            } else {
                System.out.println("Permiso NO  Modificado");
            }
        } catch (SQLException ex) {
        }
    }

    public ArrayList<Informe> consultarInformePublico() {
        String sqlQuery = "select * from postgres.informe where publico= true";
        ArrayList listaInformes = new ArrayList<Informe>();
        try {
            Statement stmt = conexion.createStatement();
            ResultSet rs = stmt.executeQuery(sqlQuery);
            while (rs.next()) {
                Informe inf = new Informe();
                inf.setNombre(rs.getString("nombre"));
                inf.setIdinforme(rs.getString("idinforme"));
                listaInformes.add(inf);
                System.out.println(rs.getString("idinforme"));
            }

        } catch (SQLException ex) {
            System.err.println("error");
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return listaInformes;
    }

    public boolean agregarPermisoAccion(String accion, String permiso) {
        try {
            String sqlquery = "INSERT INTO postgres.accion VALUES (accion,permiso) VALUES ";
            sqlquery += "('" + accion + "' , '" + permiso + "'" + ")";
            Statement stmt = conexion.createStatement();
            int agregado = stmt.executeUpdate(sqlquery);
            System.out.println(sqlquery);
            if (agregado > 0) {
                System.out.println("Permiso y accion agregado");
                return true;
            } else {
                System.out.println("Permiso y accion no agregado");
                return false;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public String consultarPermisoAccion(String accion) {
        try {
            String sqlquery = "SELECT DISTINCT permiso FROM postgres.accion WHERE nombre =";
            sqlquery += "'" + accion + "'";
            Statement stmt = conexion.createStatement();
            System.out.println(sqlquery);
            ResultSet rs = stmt.executeQuery(sqlquery);

            if (rs.next()) {
                String permisoconsultado = rs.getString("permiso");
                return permisoconsultado;
            } else {
                return null;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     *
     * OPERACIONES INFORME
     *
     */
    public static boolean agregarInforme(Informe inf) {
        FormFile ruta = inf.getRuta();
        System.out.println(ruta.getFileName());
        String query = "Insert into postgres.informe(nombre,publico,ruta) VALUES('" + inf.getNombre() + "','" + inf.getPublico() + "','./" + ruta.getFileName() + "')";
        boolean result = false;
        try {
            Statement stmt = conexion.createStatement();
            int respuesta = stmt.executeUpdate(query);
            if (respuesta > 0) {
                result = true;
            } else {
                result = false;
            }
        } catch (SQLException sql) {
            sql.printStackTrace();
        }

        return result;

    }

    /**
     *
     * @param informe
     * @return
     */
    public Informe consultarInforme(Informe informe) {
        try {
            String query = " SELECT * from postgres.informe WHERE idinforme = \'" + informe.getIdinforme() + "\'";
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" PROBLEMA Consultando el informe");
                return null;
            }
            informe.setIdinforme(rs.getString("idinforme"));
            informe.setNombre(rs.getString("nombre"));
            //System.out.println(query);
            informe.setPublico("t".equals(rs.getString("publico")));
            //informe.setRuta(rs.getString("ruta"));
            return informe;

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return informe;
    }

    /**
     *
     * @param informe
     * @return la ruta en la que se encuentra el informe
     */
    public String consultarRutaInforme(Informe informe) {
        try {
            String query = " SELECT * from postgres.informe WHERE idinforme = \'" + informe.getIdinforme() + "\'";
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            if (!rs.next()) {
                System.out.println(" PROBLEMA Consultando el informe");
                return null;
            }

            String ruta = rs.getString("ruta");
            return ruta;

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Hace la consulta de los informes que se encuentran en la base de datos.
     *
     * @param i
     * @return lista de informes.
     */
    public ArrayList<Informe> consultarInformes(Informe i) {
        ArrayList<Informe> informes = new ArrayList<Informe>(0);
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("Select * from informe");
            while (rs.next()) {
                Informe informe = new Informe(rs.getString("idinforme"), rs.getString("nombre"), null, "t".equals(rs.getString("publico")));
                //informe.setNombre(rs.getString("nombre"));
                System.out.println("consultando informe " + rs.getString("nombre"));
                informes.add(informe);
            }

        } catch (SQLException sql) {
            System.err.println("Error en la consulta de recordatorio");
            return null;
        }


        return informes;
    }

    /**
     * Hace la consulta de los informes que se encuentran en la base de datos.
     *
     * @param i
     * @return lista de informes.
     */
    public ArrayList<Informe> consultarInformesPublicos(Informe i) {
        ArrayList<Informe> informes = new ArrayList<Informe>(0);
        Connection c = DataBaseManager.conexion;
        try {
            Statement statement = c.createStatement();
            ResultSet rs = statement.executeQuery("Select * from informe where publico='t'");
            while (rs.next()) {
                Informe informe = new Informe(rs.getString("idinforme"), rs.getString("nombre"), null, "true".equals(rs.getString("publico")));
                //informe.setNombre(rs.getString("nombre"));
                System.out.println("consultando informe " + rs.getString("nombre"));
                informes.add(informe);
            }

        } catch (SQLException sql) {
            System.err.println("Error en la consulta de recordatorio");
            return null;
        }


        return informes;
    }

    /**
     * Eliminar un informe
     *
     * @param informe
     * @return indicador de si fue exitosa o no la operacion.
     */
    public boolean eliminarInforme(Informe informe) {
        boolean exitoso = true;
        try {
            Connection c = DataBaseManager.conexion;
            Statement statement = c.createStatement();
            statement.executeUpdate("delete from postgres.informe where idinforme='" + informe.getIdinforme() + "'");
            statement.close();
        } catch (SQLException e) {
            System.err.println("Error: No se ejecutó la eliminacion");
            return false;
        }
        return exitoso;

    }
    /*
     *
     * SECCION DE INDICADORES
     *
     */

    /**
     * Agrega a estructura del indicador mas la formula que contiene
     *
     * @param in : Indicador
     * @return indicador con informacion agregada, null si es invalido
     */
    public Indicador agregarIndicador(Indicador in) {
        boolean agregado = false;
        try {
            String query = "Insert into postgres.indicador(nombre) VALUES('" + in.getNombre() + "')";
            Statement stmt = conexion.createStatement();

            int respuesta = stmt.executeUpdate(query);
            if (respuesta > 0) {
                agregado = true;
            } else {
                return null;
            }
            String select = "SELECT idindicador FROM postgres.indicador WHERE nombre ='" + in.getNombre() + "'";
            ResultSet rs = stmt.executeQuery(select);

            if (rs.next()) {
                in.setIdIndicador(rs.getInt("idindicador"));
            }
            //Ahora realizare las agregaciones de las totalizaciones
            if (in.getElementos() != null) {
                IndicadorElementos elemento = agregarIndicadorElemento(in.getElementos(), in);
                if (elemento == null) {
                    return null;
                }
                in.setElementos(elemento);
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return in;
    }

    /**
     * Agrega un IndicadorElemento y se encarga de guardar los
     * IndicadorTotalizacion
     *
     * @param elemento : IndicadorElemento a agregar
     * @param indicador : Indicador al que pertenece elemento
     * @return elemento
     */
    public IndicadorElementos agregarIndicadorElemento(IndicadorElementos elemento, Indicador indicador) {
        try {
            IndicadorTotalizacion t1 = elemento.getIndicadorTotalizacion1();
            IndicadorTotalizacion t2 = elemento.getIndicadorTotalizacion2();
            if (t1 != null) {
                t1 = agregarTotalizacionAIndicador(t1);
            }
            if (t2 != null) {
                t2 = agregarTotalizacionAIndicador(t2);
            }
            String insert = "";
            String select = "";
            //Hacer insert
            if (t1 != null && t2 != null) {
                insert = "Insert into postgres.indicadorelemento(idindicadortotaliz1, idindicadortotaliz2, operacion, valor,idindicador) VALUES("
                        + t1.getIdIndicadorTotalizacion() + "," + t2.getIdIndicadorTotalizacion() + ",'" + elemento.getOperacion() + "'," + elemento.getValor() + " )";
                select = "Select idindicadorelemento from indicadorelemento WHERE idindicadortotaliz1=" + elemento.getIndicadorTotalizacion1().getIdIndicadorTotalizacion() + " AND"
                        + " idindicadortotaliz2=" + elemento.getIndicadorTotalizacion2().getIdIndicadorTotalizacion() + " AND operacion='" + elemento.getOperacion() + "' AND valor=" + elemento.getValor() + " AND"
                        + " idindicador=" + indicador.getIdIndicador();
            } else if (t1 != null && t2 == null) {
                System.out.println("\t POR AQUI NO ?? ");
                insert = "Insert into postgres.indicadorelemento(idindicadortotaliz1, idindicadortotaliz2, operacion, valor, idindicador) VALUES("
                        + t1.getIdIndicadorTotalizacion() + "," + t2 + ",'" + elemento.getOperacion() + "'," + elemento.getValor() + "," + indicador.getIdIndicador() + " )";
                select = "Select idindicadorelemento from indicadorelemento WHERE idindicadortotaliz1=" + elemento.getIndicadorTotalizacion1().getIdIndicadorTotalizacion() + " AND"
                        + " idindicadortotaliz2=" + t2 + " AND operacion='" + elemento.getOperacion() + "' AND valor=" + elemento.getValor() + " AND"
                        + " idindicador=" + indicador.getIdIndicador();
            } else if (t1 == null && t2 != null) {
                insert = "Insert into postgres.indicadorelemento(idindicadortotaliz1, idindicadortotaliz2, operacion, valor,idindicador) VALUES("
                        + t1 + "," + t2.getIdIndicadorTotalizacion() + ",'" + elemento.getOperacion() + "'," + elemento.getValor() + " )";
                select = "Select idindicadorelemento from indicadorelemento WHERE idindicadortotaliz1=" + t1 + " AND"
                        + " idindicadortotaliz2=" + elemento.getIndicadorTotalizacion2().getIdIndicadorTotalizacion() + " AND operacion='" + elemento.getOperacion() + "' AND valor=" + elemento.getValor() + " AND"
                        + " idindicador=" + indicador.getIdIndicador();
            } else {
                System.out.println("No se pudo agregar un elemento");
                return null;
            }
            Statement stmt = conexion.createStatement();
            int respuesta = stmt.executeUpdate(insert);
            if (respuesta < 0) {
                return null;
            }

            ResultSet rs = stmt.executeQuery(select);
            System.out.println(select + "\n");

            if (rs.next()) {
                elemento.setIdIndicadorElementos(rs.getInt("idindicadorelemento"));
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return elemento;
    }

    /**
     * Agrega parte de la formula al indicador
     *
     * @param in la formula
     * @param indicador el indicador a agregarle la formula.
     * @return
     */
    public IndicadorTotalizacion agregarTotalizacionAIndicador(IndicadorTotalizacion in) {
        try {
            String query = "";
            if (in.getValor() > 0) {
                query = "Insert into postgres.indicadortotaliz(idtotalizac1, idtotalizac2, operacion, valor) VALUES("
                        + in.getTotalizacion1().getIdTotalizacion() + "," + in.getTotalizacion2().getIdTotalizacion() + ",'" + in.getOperacion() + "'," + in.getValor() + " )";
            } else {
                query = "Insert into postgres.indicadortotaliz(idtotalizac1, idtotalizac2, operacion) VALUES("
                        + in.getTotalizacion1().getIdTotalizacion() + "," + in.getTotalizacion2().getIdTotalizacion() + ",'" + in.getOperacion() + "')";
            }
            Statement stmt = conexion.createStatement();
            System.out.println(query + "\n");
            int respuesta = stmt.executeUpdate(query);
            if (respuesta < 0) {
                return null;
            }
            String select = "Select idindicadortotaliz from indicadortotaliz WHERE idtotalizac1=" + in.getTotalizacion1().getIdTotalizacion() + " AND"
                    + " idtotalizac2=" + in.getTotalizacion2().getIdTotalizacion() + " AND operacion='" + in.getOperacion() + "'";
            ResultSet rs = stmt.executeQuery(select);
            System.out.println(select + "\n");

            if (rs.next()) {
                in.setIdIndicadorTotalizacion(rs.getInt("idindicadortotaliz"));
            }

//             if (in.getValor() > 0){
//               select= "Select idindicadortotaliz from indicadortotaliz WHERE idtotalizac1="+in.getTotalizacion1().getIdTotalizacion()+" AND"
//             + " operacion='"+in.getOperacion()+"' AND valor="+in.getValor();  
//             }
//             else{
//                 select= "Select idindicadortotaliz from indicadortotaliz WHERE idtotalizac1="+in.getTotalizacion1().getIdTotalizacion()+" AND"
//             + " idtotalizac2="+in.getTotalizacion2().getIdTotalizacion()+" AND operacion='"+in.getOperacion()+"'";
//             }
//             ResultSet rs = stmt.executeQuery(select);
//           
//             System.out.println(select+"\n");
//             
//             if (rs.next()){
//                 System.out.println("El indicadorTotaliz es " + rs.getInt("idindicadortotaliz"));
//                 in.setIdIndicadorTotalizacion(rs.getInt("idindicadortotaliz"));
//             }
//             else{
//                 return null;
//             }


        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return in;
    }

    /**
     * Consulta informacion basica sobre los indicadores (nombre y su id)
     *
     * @return Coleccion de Indicadores.
     */
    public ArrayList<Indicador> consultarIndicadores() {
        ArrayList<Indicador> indicadores = new ArrayList<Indicador>();
        try {


            String query = "Select idindicador, nombre FROM postgres.indicador";
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            while (rs.next()) {
                Indicador indicador = new Indicador();
                indicador.setIdIndicador(rs.getInt("idindicador"));
                indicador.setNombre(rs.getString("nombre"));
                indicadores.add(indicador);
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return indicadores;
    }

    /**
     *
     */
    public Indicador consultarIndicador(int idIndicador) {
        Indicador indicador = new Indicador();
        try {
            String query = "Select nombre FROM postgres.indicador WHERE idindicador=" + idIndicador;
            Statement stmt = conexion.createStatement();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);

            if (rs.next()) {
                indicador.setIdIndicador(idIndicador);
                indicador.setNombre(rs.getString("nombre"));
            } else {
                return null;
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return indicador;
    }

    public IndicadorElementos consultarIndicadorElementos(Indicador indicador, String ano, String trimestre, String tipo) {
        IndicadorElementos elementos = new IndicadorElementos();
        try {
            Statement stmt = conexion.createStatement();
            String query = "Select * from indicadorelemento WHERE idindicador=" + indicador.getIdIndicador();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            IndicadorTotalizacion ind = new IndicadorTotalizacion();
            if (rs.next()) {
                elementos.setIdIndicadorElementos(rs.getInt("idindicadorelemento"));
                ind.setIdIndicadorTotalizacion(rs.getInt("idindicadortotaliz1"));
                ind = consultarIndicadorTotalizacion(ind, ano, trimestre, tipo);
                elementos.setOperacion(rs.getString("operacion"));
                elementos.setValor(rs.getInt("valor"));
            }
            elementos.setIndicadorTotalizacion1(ind);
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return elementos;
    }

    public IndicadorTotalizacion consultarIndicadorTotalizacion(IndicadorTotalizacion ind, String ano, String trimestre, String tipo) {
        IndicadorTotalizacion indicador = new IndicadorTotalizacion();
        try {
            Statement stmt = conexion.createStatement();
            String query = "Select * from indicadortotaliz WHERE idindicadortotaliz=" + ind.getIdIndicadorTotalizacion();
            System.out.println(query);
            ResultSet rs = stmt.executeQuery(query);
            if (rs.next()) {
                System.out.println("IDTOTALIZAC1 " + rs.getInt("idtotalizac1"));

                Totalizacion t1 = this.consultarTotalizacionPorId(rs.getInt("idtotalizac1"));
                System.out.println("Totalizacion t1" + t1.getNombre());
                System.out.println("Tipo, ano, trimestre" + tipo + " " + ano + " " + trimestre);
                t1 = this.obtenerCeldasTotalizacion(t1, tipo, ano, trimestre);

                System.out.println("La totalizacino t1 : " + t1.getNombre());
                Totalizacion t2 = new Totalizacion();
                indicador.setTotalizacion1(t1);
                if ((rs.getInt("idtotalizac2")) != 0) {
                    System.out.println("IdTotalizac2 " + rs.getInt("idtotalizac2"));
                    t2 = this.consultarTotalizacionPorId(rs.getInt("idtotalizac2"));
                    this.obtenerCeldasTotalizacion(t2, tipo, ano, trimestre);
                    indicador.setTotalizacion2(t2);
                }
                ind.setIdIndicadorTotalizacion(ind.getIdIndicadorTotalizacion());
                indicador.setOperacion(rs.getString("operacion"));
                indicador.setValor(rs.getInt("valor"));
            } else {
                return null;
            }

        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return indicador;
    }

    /**
     * Elimina el indicador 'indicador
     *
     * @param indicador
     * @return True si se elimino correctamente, false de lo contrario
     */
    public boolean eliminarIndicador(Indicador indicador) {
        boolean eliminado = true;
        try {

            Indicador indi = consultarIndicador(indicador.getIdIndicador());

            String eliminarIndicadorTot = "DELETE FROM postgres.indicadortotaliz WHERE"
                    + " idindicadortotaliz=" + indi.getElementos().getIndicadorTotalizacion1().getIdIndicadorTotalizacion();
            Statement stmt = conexion.createStatement();
            int respuesta = stmt.executeUpdate(eliminarIndicadorTot);
            if (respuesta < 0) {
                System.out.println("Fallo el eliminarIndicadorTot");
                return false;
            }

            String eliminarElemento = "DELETE FROM postgres.indicadorelemento WHERE "
                    + " idindicadorelemento=" + indi.getElementos().getIdIndicadorElementos();
            respuesta = stmt.executeUpdate(eliminarElemento);
            if (respuesta < 0) {
                System.out.println("Fallo el eliminarElemento");
                return false;
            }
            String eliminarIndicador = "DELETE FROM postgres.indicador WHERE idindicador=" + indicador.getIdIndicador();
            respuesta = stmt.executeUpdate(eliminarIndicador);
            if (respuesta < 0) {
                System.out.println("Fallo el eliminarIndicador");
                return false;
            }
        } catch (SQLException ex) {
            Logger.getLogger(DataBaseManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return eliminado;


    }

    public static void consultarFechas() {
        try {
            String query = "SELECT DISTINCT fecha from postgres.dato ORDER BY fecha ASC";
            Statement stmt = DataBaseManager.conexion.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            String fecha = "";
            Calendar calendario = GregorianCalendar.getInstance();
            java.util.Date fechaActual = calendario.getTime();
            DateFormat formato = new SimpleDateFormat("yyyy/mm/dd");
            String fechaAct = formato.format(fechaActual);
            String[] fechaActDiv = fechaAct.split("/");
            if (rs.next()) {
                System.out.println("Si hay un dato");
                fecha = rs.getString("fecha");
                String[] fechaDiv = fecha.split("/");
                int ano = Integer.parseInt(fechaDiv[0]);



                int anoActual = Integer.parseInt(fechaActDiv[0]);

                for (int i = ano; i <= anoActual + 1; i++) { // Para incluir el ano siguiente
                    if (!DataBaseManager.fechas.contains(String.valueOf(i))) {
                        DataBaseManager.fechas.add(String.valueOf(i));
                    }
                }

            } else {
                if (!DataBaseManager.fechas.contains(fechaActDiv[0])) {
                    DataBaseManager.fechas.add(fechaActDiv[0]);
                }
            }

        } catch (SQLException ex) {
            System.out.println("Error Consultando fechas de las matrices");
        }
    }

    private String extraerAno(String fecha) {
        String[] fechaDiv = fecha.split("/");
        return fechaDiv[0];
    }

    private String extraerTrimestre(String fecha) {
        String[] fechaArr = fecha.split("/");
        int mes = Integer.parseInt(fechaArr[1]);
        String trimestre = "";


        if (1 <= mes && mes <= 3) {
            trimestre = "I";
        } else if (4 <= mes && mes <= 6) {
            trimestre = "II";
        } else if (7 <= mes && mes <= 9) {
            trimestre = "III";
        } else {
            trimestre = "IV";
        }

        return trimestre;
    }
}
